package cn.signalpha.modules.shop.service;

import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.secure.utils.AuthUtil;
import cn.signalpha.core.tool.constant.RoleConstant;
import cn.signalpha.core.tool.constant.SystemConstant;
import cn.signalpha.core.tool.node.ForestNodeMerger;
import cn.signalpha.core.tool.utils.CollectionUtil;
import cn.signalpha.core.tool.utils.Func;
import cn.signalpha.modules.shop.entity.SellerRole;
import cn.signalpha.modules.shop.entity.SellerRoleMenu;
import cn.signalpha.modules.shop.mapper.SellerRoleMapper;
import cn.signalpha.modules.shop.vo.SellerRoleVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务类
 *
 * @author signalpha
 */
@Service
@Validated
@AllArgsConstructor
public class SellerRoleService extends ServiceImpl<SellerRoleMapper, SellerRole> {

	private final SellerRoleMenuService sellerRoleMenuService;

	/**
	 * 自定义分页
	 */
    public IPage<SellerRoleVO> selectRolePage(IPage<SellerRoleVO> page, Map<String, Object> params) {
        return page.setRecords(baseMapper.selectRolePage(page, params));
    }

	public List<SellerRoleVO> tree(Long sellerId) {
		String userRole = AuthUtil.getUserRole();
		String excludeRole = null;
		if (!CollectionUtil.contains(Func.toStrArray(userRole), RoleConstant.ADMIN) && !CollectionUtil.contains(Func.toStrArray(userRole), RoleConstant.ADMINISTRATOR)) {
			excludeRole = RoleConstant.ADMIN;
		}
		return ForestNodeMerger.merge(baseMapper.tree(sellerId, excludeRole));
	}

	@Transactional(rollbackFor = Exception.class)
	public boolean grant(@NotEmpty List<Long> roleIds, List<Long> menuIds) {
		return grantRoleMenu(roleIds, menuIds);
	}

	private boolean grantRoleMenu(List<Long> roleIds, List<Long> menuIds) {
		// 防止越权配置超管角色
		Long administratorCount = baseMapper.selectCount(Wrappers.<SellerRole>query().lambda().eq(SellerRole::getRoleAlias, RoleConstant.ADMINISTRATOR).in(SellerRole::getId, roleIds));
		if (!AuthUtil.isAdministrator() && administratorCount > 0) {
			throw new ServiceException("无权配置超管角色!");
		}
		// 防止越权配置管理员角色
		Long adminCount = baseMapper.selectCount(Wrappers.<SellerRole>query().lambda().eq(SellerRole::getRoleAlias, RoleConstant.ADMIN).in(SellerRole::getId, roleIds));
		if (!AuthUtil.isAdmin() && adminCount > 0) {
			throw new ServiceException("无权配置管理员角色!");
		}
		// 删除角色配置的菜单集合
		sellerRoleMenuService.remove(Wrappers.<SellerRoleMenu>update().lambda().in(SellerRoleMenu::getRoleId, roleIds));
		// 组装配置
		List<SellerRoleMenu> sellerRoleMenus = new ArrayList<>();
		roleIds.forEach(roleId -> menuIds.forEach(menuId -> {
			SellerRoleMenu sellerRoleMenu = new SellerRoleMenu();
			sellerRoleMenu.setRoleId(roleId);
			sellerRoleMenu.setMenuId(menuId);
			sellerRoleMenus.add(sellerRoleMenu);
		}));
		// 新增配置
		sellerRoleMenuService.saveBatch(sellerRoleMenus);
		// 递归设置下属角色菜单集合
		recursionRoleMenu(roleIds, menuIds);
		return true;
	}

	private void recursionRoleMenu(List<Long> roleIds, List<Long> menuIds) {
		roleIds.forEach(roleId -> baseMapper.selectList(Wrappers.<SellerRole>query().lambda().eq(SellerRole::getParentId, roleId)).forEach(role -> {
			List<SellerRoleMenu> sellerRoleMenuList = sellerRoleMenuService.list(Wrappers.<SellerRoleMenu>query().lambda().eq(SellerRoleMenu::getRoleId, role.getId()));
			// 子节点过滤出父节点删除的菜单集合
			List<Long> collectRoleMenuIds = sellerRoleMenuList.stream().map(SellerRoleMenu::getMenuId).filter(menuId -> !menuIds.contains(menuId)).collect(Collectors.toList());
			if (collectRoleMenuIds.size() > 0) {
				// 删除子节点权限外的菜单集合
				sellerRoleMenuService.remove(Wrappers.<SellerRoleMenu>update().lambda().eq(SellerRoleMenu::getRoleId, role.getId()).in(SellerRoleMenu::getMenuId, collectRoleMenuIds));
				// 递归设置下属角色菜单集合
				recursionRoleMenu(Collections.singletonList(role.getId()), menuIds);
			}
		}));
	}

	public String getRoleIds(String tenantId, String roleNames) {
		List<SellerRole> sellerRoleList = baseMapper.selectList(Wrappers.<SellerRole>query().lambda().eq(SellerRole::getSellerId, tenantId).in(SellerRole::getRoleName, Func.toStrList(roleNames)));
		if (sellerRoleList != null && sellerRoleList.size() > 0) {
			return sellerRoleList.stream().map(role -> Func.toStr(role.getId())).distinct().collect(Collectors.joining(","));
		}
		return null;
	}

	public List<String> getRoleNames(String roleIds) {
		return baseMapper.getRoleNames(Func.toLongArray(roleIds));
	}

	public List<String> getRoleAliases(String roleIds) {
		return baseMapper.getRoleAliases(Func.toLongArray(roleIds));
	}

	public boolean submit(SellerRole sellerRoleDTO) {
		if (!AuthUtil.isAdministrator()) {
			if (Func.toStr(sellerRoleDTO.getRoleAlias()).equals(RoleConstant.ADMINISTRATOR)) {
				throw new ServiceException("无权限创建超管角色！");
			}
		}
		if (Func.isEmpty(sellerRoleDTO.getParentId())) {
			sellerRoleDTO.setSellerId(Long.valueOf(AuthUtil.getTenantId()));
			sellerRoleDTO.setParentId(SystemConstant.TOP_PARENT_ID);
		}
		if (sellerRoleDTO.getParentId() > 0) {
			SellerRole parent = getById(sellerRoleDTO.getParentId());
			if (Func.toLong(sellerRoleDTO.getParentId()) == Func.toLong(sellerRoleDTO.getId())) {
				throw new ServiceException("父节点不可选择自身!");
			}
			sellerRoleDTO.setSellerId(parent.getSellerId());
		}

		sellerRoleDTO.setIsDeleted(SystemConstant.DB_NOT_DELETED);
		return saveOrUpdate(sellerRoleDTO);
	}

	public boolean removeRole(String ids) {
		Long cnt = baseMapper.selectCount(Wrappers.<SellerRole>query().lambda().in(SellerRole::getParentId, Func.toLongList(ids)));
		if (cnt > 0L) {
			throw new ServiceException("请先删除子节点!");
		}
		return removeByIds(Func.toLongList(ids));
	}

}

